/**
 * ReportGear(2011)
 */
package net.abbp.report.model.cell.style;

import java.awt.Color;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;

import net.abbp.report.model.cell.style.background.Background;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 单元格样式
 * 
 * @version 1.0 2011-3-9
 * @author <a herf="lexloo@gmail.com">lexloo</a>
 * @since Report 1.0
 */
public class Style {
    // 日志记录
    private static Logger logger = LoggerFactory.getLogger(Style.class.getName());
    // 单元格文本样式
    private TextStyle textStyle = TextStyle.WordWrap;
    // 水平对齐方式
    private HorizentalAlignment horizentalAlignment = HorizentalAlignment.Center;
    // 垂直对齐方式
    private VerticalAlignment verticalAlignment = VerticalAlignment.Middle;
    // 边框样式
    private BorderStyle borderStyle = BorderStyle.DEFAULT_STYLE;
    // 字体样式
    private FontStyle fontStyle = FontStyle.DEFAULT_STYLE;
    // 背景
    private Background background = null;
    // 格式化样式key
    private String formatterKey = "";
    // 样式缓存
    private static Map<Style, Style> cachedStyle = new WeakHashMap<Style, Style>();
    // 默认样式
    public static Style DEFAULT_STYLE = new Style();

    public static Style getInstance() {
        Style tmpStyle = new Style();
        Style style = cachedStyle.get(tmpStyle);

        if (null != style) {
            return style;
        }

        cachedStyle.put(tmpStyle, tmpStyle);

        if (logger.isDebugEnabled()) {
            logger.debug("添加新单元格样式, 样式总数:{}", cachedStyle.size());
        }

        return tmpStyle;
    }

    public static Style getInstance(Background background, String formatter, FontStyle fontStyle,
            BorderStyle borderStyle, HorizentalAlignment horizentalAlignment, VerticalAlignment verticalAlignment,
            TextStyle textStyle) {
        Style tmpStyle = new Style(background, formatter, fontStyle, borderStyle, horizentalAlignment,
                verticalAlignment, textStyle);
        Style style = cachedStyle.get(tmpStyle);

        if (style != null) {
            return style;
        }

        cachedStyle.put(tmpStyle, tmpStyle);

        return tmpStyle;
    }

    /**
     * 获取所有样式
     * 
     * @return 所有样式
     */
    public static Set<Style> getStyleSet() {
        return Collections.unmodifiableSet(cachedStyle.keySet());
    }

    public Style deriveBorder(BorderStyle borderStyle) {
        return getInstance(this.background, this.formatterKey, this.fontStyle, borderStyle, this.horizentalAlignment,
                this.verticalAlignment, this.textStyle);
    }

    public Style deriveBorder(int topStyle, Color topColor, int leftStyle, Color leftColor, int bottomStyle,
            Color bottomColor, int rightStyle, Color rightColor) {

        BorderStyle tmpBorder = new BorderStyle(topStyle, topColor, leftStyle, leftColor, bottomStyle, bottomColor,
                rightStyle, rightColor);

        return getInstance(this.background, this.formatterKey, this.fontStyle, tmpBorder, this.horizentalAlignment,
                this.verticalAlignment, this.textStyle);
    }

    public Style deriveFormatterKey(String formatter) {
        return getInstance(this.background, formatter, this.fontStyle, this.borderStyle, this.horizentalAlignment,
                this.verticalAlignment, this.textStyle);
    }

    public Style deriveReportFont(FontStyle fontStyle) {
        return getInstance(this.background, this.formatterKey, fontStyle, this.borderStyle, this.horizentalAlignment,
                this.verticalAlignment, this.textStyle);
    }

    public Style deriveReportAlign(HorizentalAlignment horizentalAlignment, VerticalAlignment verticalAlignment,
            TextStyle textStyle) {
        return getInstance(this.background, this.formatterKey, this.fontStyle, this.borderStyle, horizentalAlignment,
                verticalAlignment, textStyle);
    }

    public Style derivetHorizentalAlignment(HorizentalAlignment horizentalAlignment) {
        return getInstance(this.background, this.formatterKey, this.fontStyle, this.borderStyle, horizentalAlignment,
                this.verticalAlignment, this.textStyle);
    }

    public Style derivetVerticalAlignment(VerticalAlignment verticalAlignment) {
        return getInstance(this.background, this.formatterKey, this.fontStyle, this.borderStyle,
                this.horizentalAlignment, verticalAlignment, this.textStyle);
    }

    public Style derivetTextStyle(TextStyle textStyle) {
        return getInstance(this.background, this.formatterKey, this.fontStyle, this.borderStyle,
                this.horizentalAlignment, this.verticalAlignment, textStyle);
    }

    /**
     * 构造器
     */
    private Style() {
    }

    /**
     * 构造器
     * 
     * @param background 背景
     * @param formatter 格式化器
     * @param fontStyle 字体样式
     * @param borderStyle 边框样式
     * @param horizentalAlignment 水平对齐
     * @param verticalAlignment 垂直对齐
     * @param textStyle 文本样式
     */
    private Style(Background background, String formatter, FontStyle fontStyle, BorderStyle borderStyle,
            HorizentalAlignment horizentalAlignment, VerticalAlignment verticalAlignment, TextStyle textStyle) {
        this.background = background;
        this.formatterKey = formatter;
        this.fontStyle = fontStyle;
        this.borderStyle = borderStyle;
        this.horizentalAlignment = horizentalAlignment;
        this.verticalAlignment = verticalAlignment;
        this.textStyle = textStyle;
    }

    public TextStyle getTextStyle() {
        return textStyle;
    }

    public HorizentalAlignment getHorizentalAlignment() {
        return this.horizentalAlignment;
    }

    public VerticalAlignment getVerticalAlignment() {
        return this.verticalAlignment;
    }

    public BorderStyle getBorderStyle() {
        if (this.borderStyle == null) {
            return BorderStyle.DEFAULT_STYLE;
        }

        return this.borderStyle;
    }

    public FontStyle getFontStyle() {
        if (this.fontStyle == null) {
            return FontStyle.DEFAULT_STYLE;
        }

        return this.fontStyle;
    }

    public Background getBackground() {
        return this.background;
    }

    public String getFormatterKey() {
        return this.formatterKey;
    }

    public int getPaddingRight() {
        // TODO Auto-generated method stub
        return 0;
    }

    public double getPaddingLeft() {
        // TODO Auto-generated method stub
        return 0;
    }

    public double getSpacingBefore() {
        // TODO Auto-generated method stub
        return 0;
    }

    public double getSpacingAfter() {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((background == null) ? 0 : background.hashCode());
        result = prime * result + ((borderStyle == null) ? 0 : borderStyle.hashCode());
        result = prime * result + ((fontStyle == null) ? 0 : fontStyle.hashCode());
        result = prime * result + ((formatterKey == null) ? 0 : formatterKey.hashCode());
        result = prime * result + ((horizentalAlignment == null) ? 0 : horizentalAlignment.hashCode());
        result = prime * result + ((textStyle == null) ? 0 : textStyle.hashCode());
        result = prime * result + ((verticalAlignment == null) ? 0 : verticalAlignment.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Style other = (Style) obj;
        if (background == null) {
            if (other.background != null)
                return false;
        } else if (!background.equals(other.background))
            return false;
        if (borderStyle == null) {
            if (other.borderStyle != null)
                return false;
        } else if (!borderStyle.equals(other.borderStyle))
            return false;
        if (fontStyle == null) {
            if (other.fontStyle != null)
                return false;
        } else if (!fontStyle.equals(other.fontStyle))
            return false;
        if (formatterKey == null) {
            if (other.formatterKey != null)
                return false;
        } else if (!formatterKey.equals(other.formatterKey))
            return false;
        if (horizentalAlignment == null) {
            if (other.horizentalAlignment != null)
                return false;
        } else if (!horizentalAlignment.equals(other.horizentalAlignment))
            return false;
        if (textStyle == null) {
            if (other.textStyle != null)
                return false;
        } else if (!textStyle.equals(other.textStyle))
            return false;
        if (verticalAlignment == null) {
            if (other.verticalAlignment != null)
                return false;
        } else if (!verticalAlignment.equals(other.verticalAlignment))
            return false;
        return true;
    }
}
